因為Java(大部分程式語言都是)是使用IEEE754演算標準,小數計算會有誤差,所以需要精確的做四則運算,需用更適用的類別來處理。
在Java中整數的最大值為9223372036854775807,最小值是-9223372036854775808,如果要表示超過這個範圍的數字,就要使用BigInteger類別。
因為數字已經大於int及long的範圍了,所以傳入BigInteger中時會使用String
BigInteger n = new BigInteger("9223372036854775808");
四則運算則要用add、subtract、multiply、divide等(有BigInteger.ONE、BigInteger.TEN等保留字)
BigInteger n1 = new BigInteger("9223372036854775808");
BigInteger n2 = new BigInteger("9223372036854775809");
n.add(n2);
n.subtract(n2);
n.multiply(n2);
n.divide(n2);
兩數比較則可以用equals()與compareTo()
BigInteger n1 = new BigInteger("200");
BigInteger n2 = new BigInteger("100");
n1.compareTo(n2);
//相等回傳0,n1>n2回傳1,n1<n2回傳-1
n1.equals(n2);
//等於回傳true,否則回傳false
BigInteger與基本型態之間的轉換
n1.longValue(); //轉為long
n1.intValue(); //轉為int
BigInteger.valueOf(100); //由int轉為BigInteger
如果由BigInteger轉回基本型態的數字超過基本型態可以容納的範圍,會使數字失去精度,此時就可以使用intValueExtract()、longValueExtract()等,使之拋出例外。
BigInteger n1 = new BigInteger("3333333333333333333333333");
n1.intValueExact();
//會拋出 java.lang.ArithmeticException例外
一般於Math類別常用的方法BigInteger也皆有支援(sqrt除外)
BigInteger n1 = new BigInteger("200");
BigInteger n2 = new BigInteger("100");
n1.pow(2);
n1.abs();
n1.min(n2);
n1.max(n2);
與BigInteger方法大同小異,可以防止小數計算時因IEEE754規範所造成的誤差。
比較特別的是四捨五入、無條件捨去、無條件進入的處理
先提一下Math類別的處理:
Math.round(5.4); //四捨五入
Math.ceil(5.4); //無條件進位
Math.floor(5.4); //無條件捨去
要注意,無條件進位是往數字大的方向進位,無條件捨去是往數字小的方向捨去
而此種進位方式如果牽扯到小數,有可能會因為IEEE754標準而發生誤差。
舉例:-5.5用Math.round()四捨五入的結果會是-5
此時就可以使用BigDecimal的進位方式:
BigDecimal r = new BigDecimal(-3.3456789);
BigDecimal i1 = r.setScale(3,RoundingMode.UP);
BigDecimal i2 = r.setScale(3,RoundingMode.DOWN);
BigDecimal i3 = r.setScale(3,RoundingMode.CEILING);
BigDecimal i4 = r.setScale(3,RoundingMode.FLOOR);
BigDecimal i5 = r.setScale(3,RoundingMode.HALF_UP);
BigDecimal i6 = r.setScale(3,RoundingMode.HALF_DOWN);
BigDecimal i7 = r.setScale(3,RoundingMode.HALF_EVEN);
而BigDecimal可以用setScale來設定量級r.setScale(3,RoundingMode.HALF_UP)
:這就代表四捨五入到小數點後第三位
DecimalFormat df = new DecimalFormat("#.00");
System.out.println(df.format(-3.155));
double d = -3.146;
String result = String.format("%.2f",d);
System.out.println(result);